{% extends "help/index.html" %}

{% block contentblock %}
    <div class="article">
        <div class="title">
            <div class="title-text" id="接入账号">接入账号<span
                    class="update-time"><i>更新时间:</i><i>2019-11-20</i></span></div>
        </div>
        <div class="content">
            <p>目前yourhost开放平台用户身份鉴权主要采用的是OAuth2.0，使用<strong>OAuth2 Authorization Code标准授权模式</strong>可以打通yourhost账号体系，通过这种授权模式获得用户登录授权后，可以通过SDK的接口访问用户隐私数据（比如可以访问用户订阅历史、用户已购专辑等隐私数据）。</p>
            <p>以下是OAuth2 Authorization Code标准授权协议示意图（来自ietf）：</p>
            <p><img src="/static/images/oauth/oauth_home_0.gif"
                    alt="OAuth2标准授权协议流程"></p>
            <p><span style="font-weight:bold; font-size:large;">下面来详细描述yourhostOAuth2 Authorization Code标准授权流程。</span></p>
            <p>先看流程示意图：</p>
            <p><img src="/static/images/oauth/oauth_home_1.png"
                    alt="OAuth2标准授权流程图"></p>
            <h2 id="获取访问令牌">获取访问令牌</h2>
            <ol>
                <li><p>引导用户到登录页面登录</p>
                    <p>如果合作方通过API方式接入，则需要先请求如下页面地址（一般建议从客户端发起请求，但其中state参数值必须由贵方服务端生成）：</p>
                    <div>
                        <pre><code>https://open.yourhost.com/o/authorize/?client_id=[应用公钥]&amp;response_type=code&amp;redirect_uri=[oauth2回调地址，创建应用时填写的]&amp;state=[表示合作方客户端的当前状态，可以指定任意值，认证服务器会原封不动地返回这个值，用于防止CSRF攻击]</code></pre>
                    </div>
                    <p><strong>注意：</strong></p></li>
            </ol>
            <ul>
                <li><p>state参数可选</p>
                    <p>实例如下（未进行URL编码的fromUri值是
                        ）：</p></li>
            </ul>
            <div>
                <pre><code></code></pre>
            </div>
            <p>页面实际效果如下图：</p>
            <p><img src="/static/images/oauth/oauth_home_2.png" alt="OAuth2登录页">
            </p>
            <ol>
                <li><p>用户输入账号信息成功登陆yourhost账号后，会自动引导到确认授权页，页面实际效果如下图：</p>
                    <p><img src="/static/images/oauth/oauth_home_3.png"
                            alt="OAuth2确认授权页"></p></li>
                <li><p>用户点击授权按钮确认授权后，yourhost开放平台OAuth2服务端会重定向（HTTP
                    302重定向）请求到redirect_uri（创建应用时填写的）指定的贵方服务端地址上去，code授权码参数和state参数会在URL查询参数中带上，如下：</p>
                    <div>
                        <pre><code>$redirect_uri?code=$CODE&amp;state=$STATE</code></pre>
                    </div>
                    <p>其中code是OAuth2授权码，state是步骤1传过来的参数</p>
                    <p>实例如下：</p>
                    <div>
   <pre><code>HTTP 302 Found
Location：https://xiaodu.baidu.com/saiya/auth/c41d0940b6dcd2fe6bfc783f9427d3b7?state=abc&amp;code=933cb1d1028e0e1d4e09c89fd6e90be7</code></pre>
                    </div>
                </li>
                <li><p>贵方服务端处理redirect_uri请求（即步骤3实例Location指定的请求），具体来说需要做这么几步：</p>
                    <ul>
                        <li><p>如果redirect_uri后带有state参数，先要验证state参数是否有效，如果无效则直接返回错误</p></li>
                        <li><p>提取redirect_uri后的code参数，并作为参数从我方服务端请求/o/get_token/接口，实例如下：</p>
                            <div>
     <pre><code>curl
-X POST
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
-d "grant_type=authorization_code&amp;redirect_uri=https://xiaodu.baidu.com/saiya/auth/c41d0940b6dcd2fe6bfc783f9427d3b7&amp;client_id=b617866c20482d133d5de66fceb37da3&amp;client_secret=xxxxxx&amp;code=933cb1d1028e0e1d4e09c89fd6e90be7"
https://open.yourhost.com/o/get_token/

{
 access_token: "33c09eb7b1357bf9ff19915e1b375dd7",
 expires_in: 7200,
 refresh_token: "1382f41227e3ea6a7471c60a1e528310",
}</code></pre>
                            </div>
                            <p><strong>注意：</strong></p>
                            <ul>
                                <li>code授权码有效期是2个小时，如果失效要按照步骤1、2重新获取</li>
                            </ul>
                        </li>
                        <li><p>将上面的响应结果原样返回作为redirect_uri请求的响应，注意Content-Type
                            HTTP响应头的值必须是application/json;charset=UTF-8，实例如下：</p>
                            <p><img src="/static/images/oauth/oauth_home_4.png"
                                    alt="OAuth2得到access\_token"></p></li>
                    </ul>
                </li>
            </ol>
            <h2 id="刷新访问令牌">刷新访问令牌</h2>
            <p>
                上一小节除了得到access_token以外，还得到一个refresh_token。<strong>access_token的失效时间是2个小时左右，而refresh_token的失效时间是30天。</strong>所以这个refresh_token可以用于刷新access_token访问令牌，从而可以实现某些场景的一次登录终身免登陆需求。
            </p>
            <p>刷新访问令牌分为以下两种情况：</p>
            <ol>
                <li>若access_token已超时，那么通过refresh_token刷新访问令牌会获取一个新的access_token，当然失效时间也将重置</li>
                <li>若access_token未超时，那么通过refresh_token刷新访问令牌不会改变access_token的值，但失效时间会重置，相当于续期access_token</li>
            </ol>
            <p>每次刷新访问令牌时，refresh_token的有效期也会被重置为新的30天；当access_token和refresh_token都失效时，需要用户重新登录授权。</p>
            <p>刷新access_token的接口请参考&nbsp;<a
                    href="#"
                    target="_blank">/o/refresh_token/</a>。</p>
            <h4>实例</h4>
            <pre><code>
curl -X POST -d "grant_type=refresh_token&client_id=<your_client_id>&client_secret=<your_client_secret>&refresh_token=<your_refresh_token>" https://open.yourhost.com/o/refresh_token/

curl -X POST -d "grant_type=refresh_token&client_id=RmuhX1PqvvhI43oyYYFkMzjTqrgaoVow9e8wEBdt&client_secret=UArvUbpkr8ja4sxCcXoFNeDxSzbOPkGOIimaPCzx5tp5fW7OwOmz3SU7OrHGRPaejHpLWeJ0ouvx4X2MuMZjQAbZRwiH9QDepDgg3Tq5EYSGn6JYYpDLlj8qJRpzcOtz&refresh_token=qgri6uQi3oAgoGQcHSX23LUnEELW9j" https://open-w.yourhost.com/o/refresh_token/
{
    "token_type": "Bearer",
    "expires_in": 36000,
    "access_token": "4hNtdA7J1g3mNkyVkmFC56I8oqRNEk",
    "refresh_token": "kcJ2imiZElczfkggwFvf0GfIxTVE3S",
    "scope": "read write"
}
            </code></pre>
        </div>
    </div>
{% endblock contentblock %}